package com.example.jinzproduct.server.impl;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.commons.exception.IFastException;
import com.example.commons.utils.*;
import com.example.commons.vo.TokenVO;
import com.example.jinzproduct.RedisUtil.RedisTime;
import com.example.jinzproduct.RedisUtil.RedisUtil;
import com.example.jinzproduct.dao.UserDao;
import com.example.commons.entity.UserDO;
import com.example.jinzproduct.entity.FileDO;
import com.example.jinzproduct.oss.FileService;
import com.example.jinzproduct.server.MpConfigService;
import com.example.jinzproduct.server.UserRoleService;
import com.example.jinzproduct.server.UserService;
import com.example.jinzproduct.util.FileType;
import com.example.jinzproduct.util.ImageUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.util.*;

@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserDao, UserDO> implements UserService {

    private static final String T_REG_SMS_PREFIX = "TRAINING_REG_";//培训端
    private static final String C_REG_SMS_PREFIX = "CERTIFICATE_REG_";//证书端
    private static final String O_REG_SMS_PREFIX = "ORTHER_REG_";//其他端

    //授权（必填）
    String grant_type = DataEnum.wx_grant_type.getValue();

    //微信url
    String wx_url = DataEnum.wx_authorization_url.getValue();
    @Autowired
    private MpConfigService mpConfigService;
    @Autowired
    private UserService userService;
    @Autowired
    private UserRoleService userRoleService;
    @Resource
    private RedisUtil redisUtil;
    @Autowired
    private UserDao userDao;

    private FileService sysFileService;

    @Override
    public List<UserDO> list() {
        return userDao.list();
    }


    @Override
    public List<UserDO> list1(Map map) {
        //1 根据课程id查询课程里面所有的章节
        QueryWrapper<UserDO> wrapperChapter = new QueryWrapper<>();

        wrapperChapter.like("name","admin");
        wrapperChapter.last("limit 10");
        List<UserDO> eduChapterList = baseMapper.selectList(wrapperChapter);

        return eduChapterList;
    }
    @Override
    public UserDO getByUserId(Long userId) {
        return baseMapper.selectById(userId);
    }
    @Override
    public Object login(Map member) {
        String wxId = member.get("wxId").toString();
        String encryptedData =member.get("encryptedData").toString();
        String iv =member.get("iv").toString();
        String code =member.get("code").toString();
        //Integer wxId, String encryptedData, String iv, String code
        if(member.size()==0){
            throw new JinZhiException(ExceptionEnum.INVALID_PARAM_ERROR.getStatus(),ExceptionEnum.INVALID_PARAM_ERROR.getMessage());
        }

        //调用微信接口获取信息 解析相应内容（转换成json对象）
        JSONObject json = JSONObject.parseObject(wxurl(wxId,code));
        String errCode = null;
        if (null != json.get("errcode")) {
            errCode = json.get("errcode").toString();
        }
        if (org.apache.commons.lang3.StringUtils.isNotBlank(errCode)) {
            String errMsg = json.getString("errmsg");
            throw new JinZhiException(ExceptionEnum.WX_ERROR_CODE.getStatus(),ExceptionEnum.WX_ERROR_CODE.getMessage()+ errMsg);
        }
        //获取会话密钥（session_key）
        String session_key = json.getString("session_key");
        //用户的唯一标识（openid）
        String openid = json.getString("openid");
        Map<String, Object> map = new HashMap<>();

        try {
            String result = AesCbcUtil.decrypt(encryptedData, session_key, iv, "UTF-8");
            JSONObject object = JSONObject.parseObject(result);
            // 拿到手机号码
            String mobile = object.getString("phoneNumber");
            if (mobile != null) {
                /////////////// 2、根据手机号码查询判断用户是否存在 ////////////////
                log.info("openId:{}", openid);
                UserDO userDO = new UserDO();
                QueryWrapper<UserDO> wrapper=new QueryWrapper<>();
                wrapper.eq("mobile",mobile);
                UserDO userDOS = userDao.selectOne(wrapper);

                if (userDOS != null) {
                    userDO = userDOS;
                    List<Long> roleIds = userRoleService.listRoleId(userDOS.getId());
                    if (roleIds != null && roleIds.size() > 0) {
                        userDOS.setRoleIds(roleIds);
                    } else {
                        List<Long> list = new ArrayList<>();
                        list.add(56L);
                        userDOS.setRoleIds(list);
                    }

                    if (wxId.equals(101)) {
                        userDOS.setCerOpenId(openid);//证书小程序openId
                    } else if (wxId.equals(102)) {
                        userDOS.setTraOpenId(openid);//培训小程序openId
                    }
                    userDao.updateById(userDOS);
                } else {
                    userDO.setUsername(mobile);//默认存入手机号码
                    userDO.setWxId(Integer.valueOf(wxId));
                    if (wxId.equals(101)) {
                        userDO.setCerOpenId(openid);//证书小程序openId
                    } else if (wxId.equals(102)) {
                        userDO.setTraOpenId(openid);//培训小程序openId
                    }
                    userDO.setMobile(mobile);
                    userDO.setType(0);//默认个人会员
                    String password = "123456";
                    String salt = UUIDUtils.get();
                    String encodePasswd = PasswdUtils.get(password, salt);
                    userDO.setSalt(salt);
                    userDO.setPassword(encodePasswd);
                    userDO.setMoney(BigDecimal.valueOf(0.0));//默认0元
                    userDO.setGmtCreate(new Date());
                    userDO.setGmtModified(userDO.getGmtCreate());
                    userDO.setStatus(1);//默认正常
                    userDO.setSex(0L);//默认未知

                    List<Long> list = new ArrayList<>();
                    list.add(56L);
                    userDO.setRoleIds(list);

                    userDao.insert(userDO);
                }

                /////////////// 3、生成自定义登录态(jwt token) ////////////////
                //生成,根据openid
                String token = getToken(mobile);

                ///////////////  4、将生成自定义登录态与session_key、openid进行关联 ////////////////
                Map cache = new HashMap();
                cache.put("session_key", session_key);
                cache.put("mobile", mobile);
                EhCacheUtil.put(token, cache);

                /////////////// 5、返回自定义登录态token + 用户信息////////////////
                map.put("isOpenId",true);//20200701 pjr新增isOpenId
                map.put("token", token);
                map.put("userId", userDO.getId());
                map.put("userName", userDO.getUsername());
                map.put("mobile", userDO.getMobile());
                map.put("headPortrait", userDO.getHeadPortrait());
                //登录成功之后，生成token字符串，使用jwt工具类
                //String jwtToken = JWTUtil.getJwtToken(userDO.getId().toString(), userDO.getId().toString());

            } else {
              //  return ApiResult.fail(ApiEnumError.USER_NOT_MOBILE.getCodeStr());
                throw new JinZhiException(ExceptionEnum.INVALID_PHONE_NULL.getStatus(),ExceptionEnum.INVALID_PHONE_NULL.getMessage());
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new JinZhiException(ExceptionEnum.TRY_CATH_ERROY.getStatus(),ExceptionEnum.TRY_CATH_ERROY.getMessage());
        }




        return map;
    }


    @Override
    public Map<String, Object> updatePersonalImg(MultipartFile file, String avatar_data, Long userId) throws Exception {
        String fileName = file.getOriginalFilename();
        fileName = UUIDUtils.get() + "." + fileName.substring(fileName.lastIndexOf(".") + 1);
        String url = "";

        // 获取图片后缀
        String prefix = fileName.substring((fileName.lastIndexOf(".") + 1));
        String[] str = avatar_data.split(",");
        // 获取截取的x坐标
        int x = (int) Math.floor(Double.parseDouble(str[0].split(":")[1]));
        // 获取截取的y坐标
        int y = (int) Math.floor(Double.parseDouble(str[1].split(":")[1]));
        // 获取截取的高度
        int h = (int) Math.floor(Double.parseDouble(str[2].split(":")[1]));
        // 获取截取的宽度
        int w = (int) Math.floor(Double.parseDouble(str[3].split(":")[1]));
        // 获取旋转的角度
        int r = Integer.parseInt(str[4].split(":")[1].replaceAll("}", ""));
        try {
            BufferedImage cutImage = ImageUtils.cutImage(file, x, y, w, h, prefix);
            BufferedImage rotateImage = ImageUtils.rotateImage(cutImage, r);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ImageIO.write(rotateImage, prefix, out);
            // 转换后存入数据库
            byte[] b = out.toByteArray();
            url = sysFileService.upload(b, fileName);
        } catch (Exception e) {
            log.warn(e.getMessage());
            throw new IFastException("图片裁剪错误！！");
        }
        Map<String, Object> result = new HashMap<>();
        FileDO sysFile = new FileDO(FileType.fileType(fileName), url, new Date());
        if (sysFileService.save(sysFile)) {
            UserDO userDO = new UserDO();
            userDO.setId(userId);
            userDO.setPicId(sysFile.getId());
            if (retBool(baseMapper.updateById(userDO))) {
                result.put("url", sysFile.getUrl());
            }
        }
        return result;
    }


    @Override
    public Long userPhone(String phone) {
        return baseMapper.userPhone(phone);
    }

    @Override
    public String getToken(String mobile) {
        QueryWrapper<UserDO> wrapper=new QueryWrapper();
        wrapper.like("mobile",mobile);
        UserDO userDO = userService.getOne(wrapper);
        if (null == userDO) {
            throw new JinZhiException(ApiEnumError.apiAuthorizationWxLoginFailed.getCode(),ApiEnumError.apiAuthorizationWxLoginFailed.getMsg());
        }
        String token =UUID.randomUUID().toString();
        //将用户信息储存到redis里面
        redisUtil.set(token,userDO.getId(), RedisTime.redisTimeDay);

        return token;
    }

    @Override
    public UserDO getUserMobile(Long mobile) {
        return baseMapper.getUserMobile(mobile);
    }

    @Override
    public UserDO getUserInfo(String token) {
        String userid=  redisUtil.get(token).toString();;
        //查询数据库根据用户id获取用户数据
        UserDO member = userService.getById(userid);
        return member;
    }

    public String wxurl(String wxId,String code){

        MpConfigDO mpConfigDO = mpConfigService.getById(wxId);
        //获取登录手机号和密码
        String params = "appid=" + mpConfigDO.getAppId() + "&secret=" + mpConfigDO.getAppSecret() + "&js_code=" + code + "&grant_type=" + grant_type;
        //发送请求
        String sr = HttpRequest.sendGet(wx_url, params);
        return sr;
    }
}
